using System;
using System.Collections.Generic;
using System.Linq;

namespace Source.Common
{
    [Serializable]
    public class ValidationSummary
    {
        private readonly List<ValidationResult> validationResults = new List<ValidationResult>();

        public void Add(ValidationResult result)
        {
            if (result != null)
            {
                validationResults.Add(result);
            }
        }

        public void AddRange(params ValidationResult[] results)
        {
            foreach (var result in results)
            {
                Add(result);
            }
        }

        public void AddRange(ValidationSummary summary)
        {
            foreach (var result in summary.validationResults)
            {
                Add(result);
            }
        }

        public bool HasWarnings
        {
            get { return HasResultsOfType(ValidationResultType.Warning); }
        }

        public bool HasErrors
        {
            get { return HasResultsOfType(ValidationResultType.Error); }
        }

        public bool HasInformationalMessages
        {
            get { return HasResultsOfType(ValidationResultType.Informational); }
        }

        public bool HasMessages
        {
            get { return HasWarnings || HasErrors || HasInformationalMessages; }
        }

        public IEnumerable<ValidationResult> GetValidationResult()
        {
            return validationResults.AsReadOnly();
        }

        public IEnumerable<string> GetErrorMessages()
        {
            return GetMessagesOfType(ValidationResultType.Error);
        }

        public IEnumerable<string> GetWarningMessages()
        {
            return GetMessagesOfType(ValidationResultType.Warning);
        }

        public IEnumerable<string> GetInformationalMessages()
        {
            return GetMessagesOfType(ValidationResultType.Informational);
        }

        public IEnumerable<string> GetMessages()
        {
            var messages = new List<string>();
            messages.AddRange(GetErrorMessages());
            messages.AddRange(GetWarningMessages());
            messages.AddRange(GetInformationalMessages());

            return messages;
        }

        private bool HasResultsOfType(ValidationResultType resultType)
        {
            return validationResults.Any(r => r.ValidationResultType == resultType);
        }

        private IEnumerable<string> GetMessagesOfType(ValidationResultType resultType)
        {
            return validationResults
                .Where(v => v.ValidationResultType == resultType)
                .Select(v => v.Message);
        }
    }
}